package cn.biplam.front.component.data.mdManage;

import java.util.Map;

import cn.biplam.common.bean.md.IndexTable;
import cn.biplam.common.bean.systemManage.Product;
import cn.biplam.common.bean.systemManage.Product.Modual_Name;
import cn.biplam.common.opcode.mdManage.TypeCode.OptModelIndexCode;
import cn.biplam.common.paramters.MdParam;
import cn.biplam.common.paramters.ModelType;
import cn.biplam.common.paramters.SysName;
import cn.biplam.common.paramters.TreeParam;
import cn.biplam.common.paramters.ModelType.Model_Type;
import cn.biplam.common.wrapper.ErrorMessage;
import cn.biplam.common.wrapper.KvMap;
import cn.biplam.common.wrapper.UserInfo;
import cn.biplam.front.component.AjxResponse;
import cn.biplam.front.component.data.tree.TreeNodeId;
import cn.biplam.front.component.view.mdManage.ModelTree;
import cn.biplam.front.html.HtmlDiv;
import cn.biplam.front.html.HtmlValue;
import cn.biplam.front.html.base.HtmlWindow;
import cn.biplam.front.html.base.Const.Window_Event;
import cn.biplam.front.htmlscript.script.AjxScript;
import cn.biplam.front.htmlscript.script.PopupScript;
import cn.biplam.front.htmlscript.script.ValueCheckScript;
import cn.biplam.front.htmlscript.script.AjxScript.Ajx_Type;
import cn.biplam.front.htmlscript.script.AjxScript.Is_SubMitData;
import cn.biplam.front.template.base.HiddenParams;
import cn.biplam.front.template.callback.tree.Bussiness_Type;
import cn.biplam.front.template.control.TreeNavigator;

/**
 * 元数据管理—业务模型管理—表、主题选择树<br>
 * <ul>用法:
 *  <li> new MdObjectSelect("根节点ID","提交动作ID") 创建表、主题选择树
 *  <li> this.setModelType("树类型")               设置树的类型即业务模型类型,默认显示源系统模型树
 *  <li> this.setShowType("树显示类型")             设置选择树显示类型(是否只显示主题),默认显示所有类型节点 
 *  <li> this.setLevelDown("向下展现级别")          设置树载入时向下展开的默认级别,默认展开一级  
 *  <li> this.setLeftBindTheme(true|false)        设置树的左键事件是否绑定到主题,默认true
 *  <li> this.setScriptActType()                  设置提交动作类型
 *  <li> this.setActionTarget                     设置提交目标容器ID
 *  <li> this.setExpandNodeId	                  设置默认展开到的节点ID
 *  <li> this.putAdditionParams                   设置页面附加参数
 *  <li> setFilterOperatorId(操作ID) 			  设置获取树叶子节点过滤列表的操作ID(OperatorId)
 *  <li> this.get("应用系统路径","用户信息") 		  获取选择树
 *  </ul>
 * @author XiaoRuxing 2009-6-16上午09:40:19
 * @version 1.0
 */
public class MdObjectSelect extends AjxResponse{

	/** 业务模型管理—表、主题选择树组件ID */
	public static final String cId="1012";
	/** 选择业务模型对象动作ID */
	private static final String Select_Md_Object="101201";
	/** 当前树 */
	private ModelTree tree;
	/** 当前树类型 */
	private Model_Type treeType;
	/** 模型对象选择树显示类型 */
	private Show_Type showType=Show_Type.All;;

	/** 根节点id*/
	private String nodeId;
	/** 向下取几级*/
	private String levelDown="1"; 

	/** 主题是否绑定左键事件 */
	private Bussiness_Type leftClickBindTheme = Bussiness_Type.SubjectBindTarget;
	/** 提交动作类型 */
	private Ajx_Type ajxType = Ajx_Type.SP;

	/** 选择树提交脚步 */
	private String submitScript;
	/** 选择树提交动作ID */
	private String submitAcId;
	/** 选择树提交刷新目标区域 */
	private String submitTarget;
	private String expandNodeId;
	/** 提交后是否关闭弹出窗口 */
	private boolean closePrompt = true;
	/** 页面附加参数容器 */
	private KvMap<String, String> addtionParams;
	/** 是否显示虚根节点 */
	private boolean showVirtualNode = false;
	/** 用户ID */
	private String userId = SysName.SysUser;
	/** 选择树的节点后,节点ID值放入的容器的页面ID */
	private static final String Container_Id = cId+"move";
	/** 节点容器iD */
	public static final String Node_Code_Container = cId+"movec";
	
	/** 获取节点过滤列表操作OperatorID */
	private String filterOperatorId = null;
	
	/**
	 * 模型对象选择树显示类型 
	 */
	public enum Show_Type{
		/** 显示业务模型下面所有对象(表和主题) */
		All,
		/** 只显示业务模型的主题 */
		Theme,
		/** 只显示业务模型根主题 */
		Root_Theme
	}

	/**
	 * @deprecated
	 */
	public MdObjectSelect(){}

	/**
	 * 创建模型对象选择树
	 * @param nodeId       根节点ID
	 * @param submitScript 选择后提交动作ID
	 */
	public MdObjectSelect(String submitActId){
		this(null,submitActId);
	}

	/**
	 * 创建模型对象选择树
	 * @param nodeId       根节点ID
	 * @param submitScript 选择后提交动作ID
	 */
	public MdObjectSelect(String nodeId , String submitActId){
		this.nodeId = nodeId;
		this.submitAcId = submitActId;
		this.addtionParams = new KvMap<String, String>();
		tree=new ModelTree();
	}

	@Override
	protected HtmlWindow ajxGet() throws ErrorMessage {
		if(this.actionId.equals(Select_Md_Object)){
			this.userId = mUser.getUserID();
			return getTable();
		}else{
			throw new ErrorMessage("Ajx Exchange outport not found:"+ actionId+" !");
		}
	}

	/**
	 *  设置用户ID
	 * @param userId
	 */
	public void setUserId(String userId){
		this.userId = userId;
	}
	
	/**
	 *  设置当前选择树 (Src,Bm,Dw,Bdsl,Dm)
	 * @param showDc 模型类型,默认为Src
	 */
	public void setModelType(Model_Type showDc){
		if(showDc==null){
			return;
		}
		this.treeType = showDc;
	}

	/**
	 *  设置当前选择树 (Src,Bm,Dw,Bdsl,Dm)
	 * @param showDc 模型类型,默认为Src
	 * @throws ErrorMessage 
	 */
	public void setModelType(String showDc) throws ErrorMessage{
		if(showDc==null){
			return;
		}
		this.treeType = ModelType.getModelType(showDc);
	}

	/**
	 *  设置选择树显示类型(是否只显示主题)
	 * @param showType 默认显示所用类型
	 */
	public void setShowType(Show_Type showType){
		if(showType==null){
			return;
		}
		this.showType = showType;
	}

	/**
	 *  设置树向下展开级别
	 * @param levelDown 默认向下1级
	 */
	public void setLevelDown(String levelDown){
		if(levelDown==null){
			return;
		}
		this.levelDown = levelDown;
	}

	/**
	 *  设置树的左键事件是否绑定到主题
	 * @param isLeftBindTheme 默认为左键绑定到主题
	 */
	public void setLeftBindTheme(boolean isLeftBindTheme){
		if(isLeftBindTheme){
			this.leftClickBindTheme = Bussiness_Type.SubjectBindTarget;
		}else{
			this.leftClickBindTheme = Bussiness_Type.Default;
		}
	}

	/**
	 *  设置提交脚本动作类型
	 * @param actionType 默认为SP方式提交
	 */
	public void setScriptActType(Ajx_Type actionType){
		this.ajxType = actionType;
	}

	/**
	 *  设置
	 * @param targetId 动作目标容器ID
	 */
	public void setActionTarget(String targetId){
		this.submitTarget = targetId;
	}

	/**
	 *  设置树载入时默认展开到节点ID
	 * @param nodeId    树节点ID
	 */
	public void setExpandNodeId(String nodeId){
		this.expandNodeId = nodeId;
	}

	/**
	 *  设置虚根节点是否可见
	 * @param isVisiable 虚根是否可见
	 */
	public void setVirturalNodeVisiable(boolean isVisiable){
		this.showVirtualNode = isVisiable;
	}

	/**
	 *  设置页面传递附加参数
	 * @param paramName  参数名称
	 * @param paramValue 参数值
	 * @throws ErrorMessage 
	 */
	public void putAdditionParams(String paramName, String paramValue) throws ErrorMessage{
		this.addtionParams.put(paramName, paramValue);
	}

	/**
	 *  设置提交后是否关闭选择窗口
	 * @param isClosePrompt 提交后是否关闭选择窗口,默认true
	 */
	public void setClosePrompt(boolean isClosePrompt){
		this.closePrompt = isClosePrompt;
	}
	
	/**
	 *  设置获取树叶子节点过滤列表的操作ID(OperatorId)
	 *   Operator操作接收的参数有：节点ID(DataFilter的默认参数), 节点真实ID(索引表的字段名称:NODE_CODE)
	 *   Operator操作返回的结果为被过滤的节点ID列表(Result)
	 * @param filterOpId 操作ID
	 */
	public void setFilterOperatorId(String filterOpId){
		this.filterOperatorId = filterOpId;
	}

	/**
	 *  设置提交脚本
	 * @throws ErrorMessage 
	 */
	private void _setScript() throws ErrorMessage{
		if(this.ajxType == null){
			return;
		}
		switch(this.ajxType){
		case PR:
			this.submitScript = AjxScript.getPr(Node_Code_Container, //提交容器ID
					this.submitAcId,                                 //提交动作ID
					Is_SubMitData.Submit                             
			);
			break;
		case SP:
			if(this.submitTarget == null){//不刷新父页面Sp提交
				this.submitScript = AjxScript.getSpNoRefresh(Node_Code_Container, 
						this.submitAcId);
			}else{//刷新父页面SP提交
				this.submitScript = AjxScript.getSp(Node_Code_Container,//提交容器ID
						this.submitAcId, //提交动作ID
						this.submitTarget//刷新目标区域ID
				);
			}
			break;
		default:
		}
		if(this.submitScript!=null && this.closePrompt){
			this.submitScript = this.submitScript+PopupScript.cancel(SysName.PromptID);
		}
		//提交前检查是否选择了模型对象
		ValueCheckScript check = new ValueCheckScript(Node_Code_Container,
				this.submitScript);
		check.putItem(Node_Code_Container+"r", "请选择模型对象!");
		this.submitScript = check.getScript();
	}

	/**
	 * 生成业务模型对象选择树<br>
	 * @param recordId  树需要展开到的节点ID 格式为： 节点ID,节点物理ID,节点级别,节点类型
	 * @param script   树节点选择后
	 * @return 业务模型对象选择树
	 * @throws ErrorMessage
	 */
	public HtmlWindow get(String sHomeUrl,UserInfo mUser) throws ErrorMessage{

		HtmlWindow div=new HtmlDiv(cId);
		div.setStyleSize("250", "260");

		/** 表选择树 */
		div.put(_getNavigator(sHomeUrl, mUser));

		/** 存放被选择节点的容器 */
		HtmlWindow valueContainer = new HtmlDiv(Node_Code_Container);
		this._setAddtionalParams(valueContainer);
		HtmlWindow value=new HtmlDiv(Container_Id);
		valueContainer.put(value);
		div.put(valueContainer);

		/**单独刷新树,传入的包含该树,且以它的大小为树的大小的容器，这里传入的是Prompt窗口正文区容器*/
		div.bind("treeResize('"+SysName.PromoptContentID+"');");

		this._setScript();
		div.bind(SysName.PromptSubmitID, Window_Event.OnClick, this.submitScript);
		return div;
	}

	/**
	 *  将附加参数放入容器
	 * @param div
	 * @throws ErrorMessage
	 */
	private void _setAddtionalParams(HtmlWindow div) throws ErrorMessage{
		if(div==null){
			return;
		}
		HtmlValue value = null;
		for(Map.Entry<String, String> param: this.addtionParams){
			value = new HtmlValue(null,","+param.getKey(),param.getValue());
			div.put(value);
		}
	}

	/**
	 * 选择表后存储当前选择的对象ID
	 */
	private HtmlWindow getTable() throws ErrorMessage{
		
		HtmlWindow value=new HtmlDiv(Container_Id);
		String nodeRealId = recordId;
		HtmlValue moveToTableID=new HtmlValue(null,Node_Code_Container+"r",nodeRealId);
		value.put(moveToTableID);
		//获取当前选择节点ID,
		TreeNodeId treeNode = new TreeNodeId(containerId);
		String nodeId = treeNode.getIndexNodeID();
		IndexTable index = IndexTable.getNewInstance(userId, MdParam.Table_Name, nodeId);
		//放入附加参数
		HiddenParams addParams = new HiddenParams();
		addParams.put(TreeParam.NODE_ID, nodeId);
		addParams.put(TreeParam.OPERATOR_TYPE, index.getOperatorType());
		addParams.put(TreeParam.NODE_TYPE, index.getNodeType());
		addParams.put(TreeParam.NAME, index.getNodeName());
		addParams.put(TreeParam.NODE_REAL_ID, nodeRealId);
		value.put(addParams.get());
		return value;
	}

	/**
	 * 生成业务模型对象选择树
	 */
	private HtmlWindow _getNavigator(String sHomeUrl,UserInfo mUser) throws ErrorMessage{
		TreeNavigator tn=new TreeNavigator(cId+"n","选择模型表",sHomeUrl,mUser);
		tree.setRightMenu(false);
		if(this.treeType!=null){
			_setTreeFilter();
			tree.setModelCallBack(this.treeType, Container_Id, Select_Md_Object,this.leftClickBindTheme.toString());
		}else{
			_setModelList();
		}
		_setShowType();
		this.tree.setFilterOperatorId(filterOperatorId);
		HtmlWindow to=tree.get(mUser, sHomeUrl, cId);
		to.setHeight("250");
		to.setWidth("200");
		tn.setTree(to);
		HtmlWindow tree = tn.get();
		return tree;
	}

	/**
	 *  设置树过滤属性
	 * @throws ErrorMessage
	 */
	private void _setTreeFilter() throws ErrorMessage{
		if(nodeId==null){
			tree.setFilter(this.treeType);
		}else{
			tree.setFilter(this.treeType, nodeId, "0", levelDown);
		}
	}

	/**
	 *  设置树显示属性
	 */
	private void _setShowType(){
		if(this.showType.equals(Show_Type.All)){
			if(this.expandNodeId!=null){
				tree.setExtendNodeID(expandNodeId);
			}
		}else if(this.showType.equals(Show_Type.Root_Theme)){
			tree.setOperatorID(OptModelIndexCode.Get_Model_Root_Theme);
		}else{	
			tree.setOnlyShowTheme(true);
		}
		if(this.showVirtualNode){
			tree.setShowVirRoot(this.showVirtualNode);
		}
	}

	/**
	 *  当未设置当前树显示类型时,根据产品发布情况显示所有发布的模型
	 */
	private void _setModelList() throws ErrorMessage{
		Product product = null;
		//设置原系统模型是否显示
		product = Product.getNewInstance(userId, Modual_Name.DBS.toString());
		if(product.modelIsDeploy()){
			tree.setFilter(Model_Type.Src);
			tree.setModelCallBack(Model_Type.Src, Container_Id, Select_Md_Object,this.leftClickBindTheme.toString());
		}
		//设置业务模型是否显示
		product = Product.getNewInstance(userId, Modual_Name.Extract.toString());
		if(product.modelIsDeploy()){
			tree.setFilter(Model_Type.Bm);
			tree.setModelCallBack(Model_Type.Bm, Container_Id, Select_Md_Object,this.leftClickBindTheme.toString());
		}
		//设置数据仓库模型是否显示
		product = Product.getNewInstance(userId, Modual_Name.EDW.toString());
		if(product.modelIsDeploy()){
			tree.setFilter(Model_Type.Dw);
			tree.setModelCallBack(Model_Type.Dw, Container_Id, Select_Md_Object,this.leftClickBindTheme.toString());
		}
	}
}
